package com.cross.jdbc;

import java.io.FileNotFoundException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;

import org.dom4j.DocumentException;

import com.cross.core.AbstractReader;
import com.cross.core.Column;
import com.cross.core.Header;
import com.cross.core.Item;
import com.cross.core.Row;
import com.cross.util.StringUtils;
import com.cross.util.ItemType;
/**
 * jdbc读入器
 * @author www
 *
 */
public class SimpleJdbcReader extends AbstractReader {
	//数据库表名
	private String table;
	//sql语句
	private String sql;
	//数据库连接
	private Connection conn;
	//结果集
	private ResultSet rs;
	//元数据结果集
	private ResultSetMetaData rsmd;
	//cross数据类型与jdbc数据类型的一个映射
	private Map<String, String> typeMap;
	
	/**
	 * 构造方法
	 */
	public SimpleJdbcReader(String table, Connection conn) throws FileNotFoundException,
			DocumentException, SQLException {
		this.table = table;
		this.conn = conn;
		typeMap = getTypeMap();
		init();
	}

	/**
	 * 初始化
	 * @throws FileNotFoundException
	 * @throws DocumentException
	 * @throws SQLException
	 */
	private void init() throws FileNotFoundException, DocumentException,
			SQLException {
		sql = "select * from " + table;
		rs = conn.createStatement().executeQuery(sql);
		rsmd = rs.getMetaData();
		header = getHeader(rsmd);
		
	}
	/**
	 * 下一行
	 */
	@Override
	protected boolean nextRow() {
		try {
			if (rs.next()) {
				currentRow = toRow(rs);
			} else {
				return false;
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}

	/**
	 * 将ResultSet转换为Row
	 * @param rs
	 * @return
	 * @throws SQLException
	 */
	private Row toRow(ResultSet rs) throws SQLException {
		Row row = new Row();
		int index = 0;
		for (Column c : header.getColumns()) {
			row.append(toItem(rs, index++, c.getType()));
		}
		return row;
	}
	/**
	 * 将rs中的一个字段转换为一个Item
	 * @param rs
	 * @param index
	 * @param type
	 * @return
	 * @throws SQLException
	 */
	private Item toItem(ResultSet rs, int index, String type)
			throws SQLException {
		Item item = new Item();
		if (ItemType.TYPE_STRING.equals(type)) {
			return new Item(rs.getString(index+1), type);
		} else if (ItemType.TYPE_INTEGER.equals(type)) {
			return new Item(rs.getInt(index+1), type);
		}
		// TODO 增加其它类型
		return item;
	}
	/**
	 * 根据ResultSetMetaData获得标题
	 * @param rsmd
	 * @return
	 * @throws SQLException
	 */
	private Header getHeader(ResultSetMetaData rsmd) throws SQLException {
		Header header = new Header();
		int count = rsmd.getColumnCount();
		String type;
		String name;
		for (int i = 0; i < count; i++) {
			type = rsmd.getColumnTypeName(i+1);
			name = rsmd.getColumnLabel(i+1);
			Column column = new Column(i, name, covertType(type));
			header.add(column);
		}
		return header;
	}

	/**
	 * 转换数据类型
	 * @param type
	 * @return
	 */
	private String covertType(String type) {
		if (StringUtils.isEmpty(type)) {
			return null;
		}
		if (typeMap.containsKey(type)) {
			return typeMap.get(type);
		}
		return type;
	}

	/**
	 * 获得数据类型映射
	 * @return
	 */
	private Map<String, String> getTypeMap() {
		Map<String, String> map = new HashMap<String, String>();
		
		map.put("CHAR", ItemType.TYPE_STRING);
		map.put("VARCHAR", ItemType.TYPE_STRING);
		//TODO 增加其它类型的映射
		return map;
	}

	/**
	 * 关闭
	 */
	@Override
	public void close() {

		try {
			rs.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}

}
